var entityCollection = require('./EntityCollection'),
    BaseEnum = require('./Enum'),
    BaseFun = require('./Function');

//1，先对第一个实体集合进行保存，保存完后通知进行下一个实体保存，如果收到实体保存的错误，则跳出并执行回滚，返回给调用端错误信息
//2，单个实体保存记录集合，先删除，然后通知修改，再通知插入，如果当前环节失败，则跳出，并返回错误
exports.BatchSaveByTran = function(entityRecords, resultHandel){
    var entitysSaves = [];

    var entityRecordIndex = -1;
    var entitySaveCallBack = function(err){
        if(err){
            for (var i=0; i<entitysSaves.length; i++) {
                entitysSaves[i].Rollback();
            }
            resultHandel(err);
        }
        else{
            if(entityRecordIndex < entityRecords.length - 1) {
                entityRecordIndex++;
                var entity = entityCollection.getEntity(entityRecords[entityRecordIndex].EntityName);
                var entitySave = new EntitySaveByTran(entity, entityRecords[entityRecordIndex].Records);
                entitysSaves.push(entitySave);
                entitySave.Save(entitySaveCallBack);
            }
            else{
                var data = [];
                for (var i=0; i<entitysSaves.length; i++) {
                    data.push({
                        EntityName: entitysSaves[i].Entity.Name,
                        Insert: entitysSaves[i].InsertRecords,
                        Update: entitysSaves[i].UpdateRecords,
                        Delete: entitysSaves[i].DeleteRecords
                    });
                }
                resultHandel(null, data);
            }
        }
    };
    entitySaveCallBack();
};

var EntitySaveByTran = function(entity, records){
    this.Entity = entity;
    this.InsertingRecords = new Array();    //插入前记录
    this.DeletingRecords = new Array();     //删除前记录
    this.UpdatingRecords = new Array();     //更新前记录

    this.InsertRecords = new Array();   //插入后的数据库记录
    this.DeleteRecords = new Array();   //删除前的数据库记录
    this.UpdateRecords = new Array();   //更新前的数据库记录
    this.ErrInfos = [];
    this.CompleteFun;

    for (var i = 0; i < records.length; i++) {
        if (records[i].RowStatus == BaseEnum.RowStatus.Insert.Value) {
            if(records[0]._id != null && records[0]._id != undefined 
                && records[0]._id.constructor === Number){
                delete records[0]._id;
            }
            this.InsertingRecords.push(records[i]);
        }
        else if (records[i].RowStatus == BaseEnum.RowStatus.Modify.Value) {
            this.UpdatingRecords.push(records[i]);
        }
        else if (records[i].RowStatus == BaseEnum.RowStatus.Delete.Value) {
            this.DeletingRecords.push(records[i]);
        }
    }

    this.Save = function(completeFun){
        var self = this;
        this.CompleteFun = completeFun;
        this.Delete(function(){
            if(self.ErrInfos.length > 0){
                self.ExecResultFun();
            }
            else{
                self.Update(function() {
                    if (self.ErrInfos.length > 0) {
                        self.ExecResultFun();
                    }
                    else {
                        self.Insert(function() {
                            self.ExecResultFun();
                        });
                    }
                });
            }
        });
    };

    this.Delete = function(completeFun){
        var self = this;
        var findRecordIndex = 0;   //当前查找记录所对应的索引位置
        var deleteRecordIndex = 0; //当前删除记录所对应的索引位置
        var findDeleteRecords = []; //查找到被删除的记录

        if(this.DeletingRecords.length > 0) {
            for (var i = 0; i < this.DeletingRecords.length; i++) {
                this.Entity.findById(this.DeletingRecords[i]._id, null, function (err, record) {
                    if (err) {
                        var newErr = new Error();
                        newErr.leval = 9;
                        newErr.title = '查询异常';
                        newErr.message = BaseFun.getErrMsgByRecord(self.Entity.Name, self.DeletingRecords[findRecordIndex], err.message);
                        self.ErrInfos.push(newErr);

                        findDeleteRecords.push(null);
                        findRecordIndex++;
                        deleteRecordIndex++;

                        if (deleteRecordIndex == self.DeletingRecords.length) {
                            completeFun();
                        }
                    }
                    else {
                        findDeleteRecords.push(record);
                        findRecordIndex++;
                        self.Entity.delete(record, function (err) {
                            if (err) {
                                var newErr = new Error();
                                newErr.leval = 9;
                                newErr.title = '删除记录异常';
                                newErr.message = BaseFun.getErrMsgByRecord(self.Entity.Name, self.DeletingRecords[deleteRecordIndex], err.message);
                                self.ErrInfos.push(newErr);
                            }
                            else {
                                self.DeleteRecords.push(findDeleteRecords[deleteRecordIndex]);
                            }
                            deleteRecordIndex++;
                            if (deleteRecordIndex == self.DeletingRecords.length) {
                                completeFun();
                            }
                        });
                    }
                });
            }
        }
        else{
            completeFun();
        }
    };

    this.Update = function(completeFun) {
        var self = this;
        var findRecordIndex = 0;    //当前查询记录所对应的索引位置
        var updateRecordIndex = 0;  //当前更新记录所对应的索引位置
        var findUpdateRecords = [];

        if(this.UpdatingRecords.length > 0) {
            for (var i = 0; i < this.UpdatingRecords.length; i++) {
                this.Entity.findById(this.UpdatingRecords[i]._id, null, function (err, record) {
                    if (err) {
                        var newErr = new Error();
                        newErr.leval = 9;
                        newErr.title = '查询异常';
                        newErr.message = BaseFun.getErrMsgByRecord(self.Entity.Name, self.UpdatingRecords[findRecordIndex], err.message);
                        self.ErrInfos.push(newErr);

                        findUpdateRecords.push(null);
                        findRecordIndex++;
                        updateRecordIndex++;

                        if (updateRecordIndex == self.UpdatingRecords.length) {
                            completeFun();
                        }
                    }
                    else {
                        findUpdateRecords.push(record);

                        self.Entity.update(self.UpdatingRecords[findRecordIndex], function (err) {
                            if (err) {
                                var newErr = new Error();
                                newErr.leval = 9;
                                newErr.title = '修改数据异常';
                                newErr.message = BaseFun.getErrMsgByRecord(self.Entity.Name, self.UpdatingRecords[updateRecordIndex], err.message);
                                self.ErrInfos.push(newErr);
                            }
                            else {
                                self.UpdateRecords.push(findUpdateRecords[updateRecordIndex]);
                            }
                            updateRecordIndex++;

                            if (updateRecordIndex == self.UpdatingRecords.length) {
                                completeFun();
                            }
                        });

                        findRecordIndex++;
                    }
                });
            }
        }
        else{
            completeFun();
        }
    };

    this.Insert = function(completeFun) {
        var self = this;
        var insertRecordIndex = 0; //当前插入记录所对应的索引位置
        if(this.InsertingRecords.length > 0) {
            for (var i = 0; i < this.InsertingRecords.length; i++) {
                this.InsertingRecords[i].SysVersion = 0;
                this.InsertingRecords[i].CreatedOn = new Date();
                this.Entity.insert(this.InsertingRecords[i], function (err, record) {
                    if (err) {
                        var newErr = new Error();
                        newErr.leval = 9;
                        newErr.title = '数据插入异常';
                        newErr.message = BaseFun.getErrMsgByRecord(self.Entity.Name, self.InsertingRecords[insertRecordIndex], err.message);
                        self.ErrInfos.push(newErr);
                    }
                    else {
                        self.InsertRecords.push(record);
                    }

                    insertRecordIndex++;
                    if (insertRecordIndex == self.InsertingRecords.length) {
                        completeFun();
                    }
                });
            }
        }
        else{
            completeFun();
        }
    };

    this.Rollback = function(){
        for(var i=0; i<this.InsertRecords.length; i++){
            this.Entity.deleteById(this.InsertRecords[i]._id);
        }
        for(var i=0; i<this.UpdateRecords.length; i++){
            this.Entity.updateByValue({_id: this.UpdateRecords[i]._id}, {$set: this.UpdateRecords[i]});
        }
        for(var i=0; i<this.DeleteRecords.length; i++){
            this.Entity.insert(this.DeleteRecords[i]);
        }
    };

    //保存执行完成执行的方法
    this.ExecResultFun = function(){
        if(this.ErrInfos.length > 0){
            var newErr = new Error();
            newErr.leval = 9;
            newErr.title = '保存失败';
            newErr.message = "";
            for(var i=0; i<this.ErrInfos.length; i++){
                if(i == 0) {
                    newErr.message += this.ErrInfos[i].title + "\n" + this.ErrInfos[i].message;
                }
                else{
                    newErr.message += '\n' + this.ErrInfos[i].title + "\n" + this.ErrInfos[i].message;
                }
            }
            this.CompleteFun(newErr);
        }
        else{
            this.CompleteFun();
        }
    };
};
